/******************************************************************************
 * @file key.h
 * 
 * @par dependencies
 * - stdio.h
 * - stdint.h
 * 
 * @author Shawn Li <2339679615@qq.com>
 * 
 * @brief Provide the HAL APIs of Key and corresponding opetions.
 * 
 * @version v0.1 2025-10-15
 * 
 * @date 2025-10-15
 * 
 * @copyright Copyright (c) 2025 Li Shan
 * All rights reserved.
 * 
 * @note 1 tap == 4 spaces!
 *       Code is UTF-8
 * 
******************************************************************************/

#ifndef __BSP_KEY_H__
#define __BSP_KEY_H__

//******************************** Includes *********************************//


#include <stdint.h>               //  the compiling lib.
#include <stdio.h>

#include "main.h"                 //  Core / OS layer
#include "cmsis_os.h"               

#include "queue.h"                //  specific file for operations
#include "stm32f4xx_hal.h"        
#include "stm32f4xx_hal_gpio.h"

//******************************** Includes *********************************//

//******************************** Defines **********************************//

typedef enum
{
	KEY_OK                = 0,         /* Operation completed successfully.  */
	KEY_ERROR             = 1,         /* Run-time error without case matched*/
	KEY_ERRORTIMEOUT      = 2,         /* Operation failed with timeout      */
	KEY_ERRORRESOURCE     = 3,         /* Resource not available.            */
	KEY_ERRORPARAMETER    = 4,         /* Parameter error.                   */
	KEY_ERRORNOMEMORY     = 5,         /* Out of memory.                     */
	KEY_ERRORISR          = 6,         /* Not allowed in ISR context         */
	KEY_RESERVED          = 0x7FFFFFFF /* Reserved                           */
} key_status_t;

typedef enum
{
	KEY_PRESSED           = 0,         /* Operation completed successfully.  */
	KEY_NOT_PRESSED       = 1,         /* Run-time error without case matched*/
	KEY_SHORT_PRESSED     = 2,         /* Operation                          */
	KEY_LONG_PRESSED      = 3,         /* Operation                          */
} key_press_status_t;

//******************************** Defines **********************************//

//******************************** Declaring ********************************//

//******************** Thread_Function ******************//
extern osThreadId_t key_TaskHandle;
extern const osThreadAttr_t key_Task_attributes;
//******************** Thread_Function ******************//


//********************* Queue_Function ******************//
extern QueueHandle_t key_queue;

//********************* Queue_Function ******************//


//********************* Function Prototypes**************//
/**
 * @brief Scan the key state (non-blocking with debounce/timeout behavior).
 *
 * Samples the configured key GPIO, applies software debounce logic and
 * returns the detected state through the output parameter @p key_value.
 *
 * @param[out] key_value Pointer to a variable that receives the key state
 *                       (KEY_PRESSED or KEY_NOT_PRESSED).
 * @return key_status_t  KEY_OK on success (state read),
 *                       KEY_ERRORTIMEOUT if a timeout occurred, or other
 *                       KEY_ERROR_* codes on failure.
 */
key_status_t key_scan                  (key_press_status_t *key_value);



/**
 * @brief This function will check the key type is short press or long press.
 *
 * Samples the configured key GPIO, applies software debounce logic and
 * returns the detected state through the output parameter @p key_value.
 *
 * @param[out] key_value Pointer to a variable that receives the key state
 *                       (KEY_PRESSED or KEY_NOT_PRESSED).
 * @param[in] short_press_time_threshold  Time threshold (in milliseconds) to
 *                      differentiate between short press and long press.
 * 
 * @return KEY_SHORT_PRESSED: The key was short pressed.
 *         KEY_LONG_PRESSED : The key was long pressed.
 */
key_status_t key_scan_short_long_press(key_press_status_t *key_value, 
                                        uint32_t    short_press_time);



/**
 * @brief Key handling thread entry function.
 *
 * This FreeRTOS task polls for key events or waits for notifications and
 * dispatches key events (for example, pushing events to @p key_queue or
 * invoking a registered callback). The @p argument parameter is the value
 * passed when the task was created and may be NULL.
 *
 * @param[in] argument Pointer passed to the task (task parameter).
 * 
 * @return void
 */
void        key_task_func                (void *argument);


//********************* Function Prototypes**************//


//******************************** Declaring ********************************//



#endif // End of __BSP_KEY_H__
